package org.dromara.system.service.impl.permission;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.constant.MachineConstant;
import org.dromara.system.converter.MachineConverters;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.base.BasePageReqDTO;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.enums.QueryTypeEnum;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.util.TreeUtil;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 王星
 * @date 2024/8/2 下午4:57
 */
@Service
@RequiredArgsConstructor
public class PermissionBaseService {

    @Resource
    private SysUserMapper sysUserMapper;

    private static void addNextUser(ArrayList<SysUserVo> addSysUsers, List<SysUserVo> sysUsers) {
        if (CollUtil.isNotEmpty(sysUsers)) {
            sysUsers.forEach(t1 -> {
                addSysUsers.add(t1);
                addNextUser(addSysUsers, t1.getChildren());
            });
        }
    }

    private static void addNextUpUser(ArrayList<SysUser> addSysUsers, SysUser childrenSysUser) {
        addSysUsers.add(childrenSysUser);
        if (ObjectUtil.isNotNull(childrenSysUser.getChildrenSysUser())) {
            addNextUpUser(addSysUsers, childrenSysUser.getChildrenSysUser());
        }
    }

    //admin 全部  其他自己
    public void assignPermission(BasePageReqDTO reqQueryDTO) {
        Long userId = reqQueryDTO.getUserId();
        if (ObjectUtil.isNull(userId)) {
            userId = LoginHelper.getUserId();
        }
        if (ObjectUtil.notEqual(userId, MachineConstant.ADMIN)) {
            reqQueryDTO.setUserIds(Collections.singletonList(userId));
        }
        reqQueryDTO.setUserId(null);
    }

    public List<Long> findUser(SysUser sysUser, Integer queryType) {
        //缓存
        List<SysUser> sysUsers = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
            .select(SysUser::getPId, SysUser::getUserId));
        List<SysUserVo> SysUserVoList = MachineConverters.INSTANCE.toSysUserVoList(sysUsers);
        //下级直属
        List<SysUserVo> sysUsersTree = TreeUtil.newListToTree(SysUserVoList, SysUserVo::setChildren, SysUserVo::getUserId,
            SysUserVo::getPId, (node) -> ObjectUtil.equal(sysUser.getPId(), node.getPId()));
        SysUserVo headed = sysUsersTree.stream().filter(t1 -> ObjectUtil.equal(t1.getUserId(), sysUser.getUserId())).findFirst().orElse(null);
        return nextUser(headed, queryType).stream()
            .map(SysUserVo::getUserId)
            .collect(Collectors.toList());
    }

    public List<SysUserVo> nextUser(SysUserVo sysUser, Integer type) {
        ArrayList<SysUserVo> addSysUsers = Lists.newArrayList();
        if (ObjectUtil.equal(type, QueryTypeEnum.TEAM.getCode())) {
            if (ObjectUtil.isNotNull(sysUser.getChildren())){
                addNextUser(addSysUsers, sysUser.getChildren());
            }
        }
        if (ObjectUtil.equal(type, QueryTypeEnum.ALL.getCode())) {
            addSysUsers.add(sysUser);
            addNextUser(addSysUsers, sysUser.getChildren());
        }
        if (ObjectUtil.equal(type, QueryTypeEnum.DIRECT.getCode())) {
            addSysUsers.add(sysUser);
        }
        if (ObjectUtil.equal(type, QueryTypeEnum.JUNIOR.getCode())) {

            if (ObjectUtil.isNotNull(sysUser.getChildren())){
                addSysUsers.addAll(sysUser.getChildren());
            }
        }
        if (ObjectUtil.equal(type, QueryTypeEnum.DIRECT_AND_DIRECT.getCode())) {
            addSysUsers.add(sysUser);
            addSysUsers.addAll(sysUser.getChildren());
        }
        if (ObjectUtil.equal(type, QueryTypeEnum.AGENT.getCode())) {
            if (CollUtil.isNotEmpty(sysUser.getChildren())) {
                sysUser.getChildren().forEach(t1 -> {
                    addNextUser(addSysUsers, t1.getChildren());
                });
            }
        }
        return addSysUsers;
    }

    public List<SysUser> findUpUserList(Long userId, Integer queryType) {
        //缓存
        SysUser sysUser = sysUserMapper.upUser(userId);
        return nextUpUser(sysUser, queryType).stream().collect(Collectors.toList());
    }

    public List<SysUser> nextUpUser(SysUser sysUser, Integer type) {
        ArrayList<SysUser> addSysUsers = Lists.newArrayList();
        if (ObjectUtil.equal(type, QueryTypeEnum.TEAM.getCode())) {
            addNextUpUser(addSysUsers, sysUser.getChildrenSysUser());
        }
        if (ObjectUtil.equal(type, QueryTypeEnum.ALL.getCode())) {
            addSysUsers.add(sysUser);
            addNextUpUser(addSysUsers, sysUser.getChildrenSysUser());
        }
        return addSysUsers;
    }


}
